﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Reflection;
using MvcEngine.Core.Utils;

using MvcEngine.Core.Services;
using System.Security.Principal;
using System.Web.Routing;
using MvcEngine.Core.Repositories;
using MvcEngine.Core.Exceptions;
using MvcEngine.Core.Website;
using MvcEngine.Core.Content;
using MvcEngine.Core.Helpers;
using System.Diagnostics;

namespace MvcEngine.Core
{
    public class SiteContext : ISiteContext
    {
        protected static readonly string currentPageKey = "CurrentPageKey";

        public SiteContext()
        {

        }

        public static ISiteContext Current
        {
            get
            {
                return IoC.Resolve<ISiteContext>();
            }
        }

        public Skin Skin
        {
            get
            {
                if (CurrentPage.SkinId.HasValue)
                {
                    return SiteManager.Current.GetSkin(CurrentPage.SkinId.Value);
                }
                return SiteManager.Current.GetSkin(this.Site.SkinId);
            }
        }

        public SkinTemplate SkinTemplate
        {
            get
            {
                if (CurrentPage.SkinTemplateId.HasValue)
                {
                    return SiteManager.Current.GetSkinTemplate(CurrentPage.SkinTemplateId.Value);
                }
                return SiteManager.Current.GetDefaultSkinTemplate(this.Skin.Id);
            }
        }

#warning Check Skin in Site. Now it's just string
        public Site Site { get; set; }

        public Page CurrentPage
        {
            get
            {
                Page page = HttpContext.Current.Items[currentPageKey] as Page;
                if (page == null)
                {
                    HttpContextBase contextWrapper = new HttpContextWrapper(HttpContext.Current);
                    RouteData routeData = RouteTable.Routes.GetRouteData(contextWrapper);
                    string pageName = null;

                    if (routeData != null && routeData.Values.ContainsKey("pageName"))
                    {
                        pageName = routeData.Values["pageName"] as string;
                        if (!string.IsNullOrEmpty(pageName))
                        {
                            page = ContentManager.Current.GetPage(pageName);
                            if (page != null)
                            {
                                HttpContext.Current.Items[currentPageKey] = page;
                                return page;
                            }
                        }
                    }

                    if (routeData != null && routeData.Values.ContainsKey("pageId"))
                    {
                        Guid pageId = new Guid(routeData.Values["pageId"].ToString());
                        page = ContentManager.Current.GetPage(pageId);
                        if (page != null)
                        {
                            HttpContext.Current.Items[currentPageKey] = page;
                            return page;
                        }
                    }

                    if (SiteContext.Current == null)
                    {
                        LogHelper.Current.WriteInfo("SiteContext is null");
                    }

                    if (SiteContext.Current.Site == null)
                    {
                        LogHelper.Current.WriteInfo(string.Format("Site is null. Request: {0}", HttpContext.Current.Request.ApplicationPath));
                    }

                    if (SiteContext.Current.Site.Fields == null || !SiteContext.Current.Site.Fields.ContainsKey("DefaultPage"))
                    {
                        LogHelper.Current.WriteInfo("Default page is not set.");
                        if (SiteContext.Current.Site.Fields == null)
                            LogHelper.Current.WriteInfo("Fields collection is empty.");
                        else
                            LogHelper.Current.WriteInfo("Count of elements in collection: " + SiteContext.Current.Site.Fields.Count);

                        try
                        {
                            string stackTrace = string.Empty;
                            StackTrace trace = new StackTrace();
                            foreach (var item in trace.GetFrames())
                            {
                                stackTrace += item.GetMethod().Name + "<br/>";
                            }
                            LogHelper.Current.WriteInfo("StackTrace: " + stackTrace);
                        }
                        catch 
                        {
                        
                        }
                    }

                    try
                    {
                        page = ContentManager.Current.GetPage(SiteContext.Current.Site.DefaultPage);
                        if (page != null)
                        {
                            HttpContext.Current.Items[currentPageKey] = page;
                            return page;
                        }
                    }
                    catch (Exception e)
                    {
                        LogHelper.Current.WriteError(e);
                    }

                    throw new BusinessException("Every route must have pageName parameter.");
                }
                return page;
            }
        }
    }
}
